﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using OpenNETCF.IoC.UI;
using OpenNETCF.IoC;
using System.IO;
using System.Diagnostics;
using System.Threading;

namespace MachineSimulator
{
    public class InstanceLog
    {
        private string m_path;

        public string LogFileName { get; private set; }

        public InstanceLog(string logName)
        {
            LogFileName = logName;
            m_path = Path.Combine(Application.StartupPath, LogFileName);
        }

        private TextWriter GetWriter()
        {
            try
            {
                if (!File.Exists(m_path))
                {
                    return File.CreateText(m_path);
                }
                else
                {
                    return File.AppendText(m_path);
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
                return null;
            }
        }

        private void WriteLine(string text)
        {
            WriteLine(text, true);
        }

        private void WriteLine(string text, bool dateTimeSuffix)
        {
            using (var writer = GetWriter())
            {
                string line;

                try
                {
                    if (dateTimeSuffix)
                    {
                        line = string.Format("{0} : {1}",
                        DateTime.Now.ToString("MM/dd/yy HH:mm:ss"),
                        text);

                        writer.WriteLine(line);
                    }
                    else
                    {
                        writer.WriteLine(text);
                    }
                }
                catch (Exception ex)
                {
                    Debug.WriteLine(ex.Message);
                }
            }
        }

        public void InstanceStarted()
        {
            WriteLine("Instance Started");
        }

        public void InstanceEnded()
        {
            WriteLine("Instance Ended");
        }

        public void UnhandledException(Exception ex)
        {
            var line = string.Format("{0} Exception\r\nMessage: {1}\r\n{2}",
                ex.GetType().Name,
                ex.Message,
                ex.StackTrace);

            WriteLine(line);
        }
    }

    public class Program : SmartClientApplication<MainForm>
    {
        static Mutex m_mutex;
        static InstanceLog log = new InstanceLog("MachineSimulator.log");

        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            // Hook up the exception handler
            AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);

            m_mutex = new Mutex(true, "MachineSimulator_mutex");

            try
            {
                log.InstanceStarted();
                new Program().Start();
                log.InstanceEnded();
            }
            catch (ServiceMissingException)
            {
                // NOTE: If you get a ServiceMissingException here, it's likely because you've deployed an extra copy of the 
                // OpenNETCF.MTConnect.Common.dll assembly into the Adapters subfolder.  Make sure CopyLocal is false on your 
                // references and the Adapters folder is clean
                MessageBox.Show("A service could not be loaded, likely because of an assembly duplication.  Please clean the Adapters folder.");
            }
            finally
            {
                m_mutex.Close();
            }
        }

        static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            log.UnhandledException(e.ExceptionObject as Exception);
        }
    }
}
